"""
功能描述：判断用例是否有前置用例
导包
    1-实例化方法
    2-定义实例化方法preSolve，接受testcase传入的数据，
        判断是否有前置用例
        1-有前置，先跑前置用例
            请求头和请求参数--以下逻辑可以单独定义实例方法
                通过读取当前header，来判断是否有依赖的header信息，判断${xxx}来获取
                去testcase中定义的testdata全局变量中取要执行的前置用例数据
                调用runpre方法获取依赖的用例信息
            将取出来的结果替换到正式用例中，返回testcase
        2-无前置，直接返回
    3-定义实例方法runPre运行前置用例，提取目标字段
        准备前置用例所需的数据
        调用confighttp方法获取接口结果
        返回目标字段的值
"""
from 高级版接口第一周.common.log import logger
from 高级版接口第一周.common.confighttp import confighttp
import re
from jsonpath import jsonpath
class PreSolve:

    def __init__(self, *testdata):
        self.testdata = testdata

    def getPreHeader(self, cur_header):
        """提取需要依赖的请求头/体字段"""
        # 请求头/体
        result = re.findall(r'\$\{(.*?)\}', cur_header)
        if len(result) != 0:
            goal_h = result[0]
            logger.debug(f'header/body中需要替换的数据为：{goal_h}')
        else:
            goal_h = None
        return goal_h

    def presolve(self, id):
        logger.debug('id: %s,testdata: %s' % (id, self.testdata))
        # 1-判断是否有前置用例
        # 准备当前接口请求所需要的数据
        rely = self.testdata[int(id) - 1]['rely']
        caseid = self.testdata[int(id) - 1]['caseid']
        cur_header = self.testdata[int(id) - 1]['header']
        cur_param = self.testdata[int(id) - 1]['value']
        logger.debug('rely: %s，caseid: %s, value: %s，cur_header: %s' % (rely, caseid, cur_param, cur_header))
        # 如果有前置，且当前用例的不是第一条用例，且被依赖的caseid不为空
        if rely.lower() == 'y' and id != '1' and caseid != '':
            # 通过读取当前header和value，来判断是否有依赖的header信息和param信息，需要提取被依赖接口的哪些字段
            logger.debug(f'用例有前置，开始获取前置用例的数据，然后替换当前用例，准备header和body')
            goal_h = self.getPreHeader(cur_header)
            goal_b = self.getPreHeader(cur_param)
            # 调用runpre方法获取依赖的用例信息
            h, b = self.runPre(caseid, goal_h, goal_b)
            # 将取出来的结果替换到正式用例中，返回testcase
            if h != None:
                cur_header = cur_header.replace('${' + goal_h + '}', h)
                logger.info(f'替换好的header为：{cur_header}')
            if b != None:
                cur_param = cur_param.replace('${' + goal_b + '}', b)
                logger.info(f'替换好的body为：{cur_param}')
            return cur_header, cur_param
        else:
            logger.debug(f'用例无前置，默认使用当前的header和body')
            return cur_header, cur_param

    def runPre(self, caseid, goal_h=None, goal_b=None):
        # 3 - 定义实例方法runPre运行前置用例，提取准备好的目标字段
        # 准备前置用例所需的数据
        logger.debug('准备运行前置用例，获取前置用例结果')
        preUrl = self.testdata[int(caseid) - 1]['interfaceUrl']
        premethod = self.testdata[int(caseid) - 1]['method']
        prevalue = self.testdata[int(caseid) - 1]['value']
        preheader = self.testdata[int(caseid) - 1]['header']
        logger.debug(f'前置用例preUrl:{preUrl}，premethod:{premethod}, prevalue:{prevalue}，preheader:{preheader}')
        # 调用confighttp方法获取接口结果
        ch = confighttp(preUrl, premethod, prevalue, preheader)
        re = ch.run()
        logger.info(f'前置用例的返回结果为：{re.text}')
        if goal_h != None:
            goal_h = re.headers[goal_h]
        if goal_b != None:
            # 调用jsonpath中的方法获取目标字段值
            goal_b = jsonpath(re.json(), "$.." + goal_b)[0]
        # 返回目标字段的值
        return goal_h, goal_b


if __name__ == '__main__':
    ps = PreSolve()
    ps.presolve()